//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using OpenLS.Core.Serialization;

namespace OpenLS.Spreadsheet
{
    public class ValuesFilter: Filter
    {
        internal override void ReadXmlCore(ReadContext context)
        {
            using (ReadContext c = context.Read(xmlName))
            {
                Blank = c.GetOptionalBoolean("blank", false);
                CalendarType = c.GetOptionalEnum("calendarType", CalendarType.None);
                Filters.Clear();
                while (c.ReaderLocalName == "filter")
                {
                    using (ReadContext c2 = c.Read("filter"))
                    {
                        Filters.Add(c2.GetString("val"));
                    }
                }
                DateGroupItems.AddRange(c.ReadOptionalWhile<DateGroupItem>("dateGroupItem"));

            }
        }
        const string xmlName = "filters";

        internal override void WriteXmlCore(WriteContext context)
        {
            using (WriteContext c = context.Write(xmlName))
            {
                c.SetOptionalBoolean("blank", Blank, false);
                c.SetOptionalEnum("calendarType", CalendarType, CalendarType.None);
                foreach (string s in Filters)
                {
                    using (WriteContext c2 = c.Write("filter"))
                    {
                        c2.SetString("val", s);
                    }
                }
                foreach (DateGroupItem i in DateGroupItems)
                    c.WriteElement(i);
            }
        }
        private readonly List<string> _filters = new List<string>();

        ///<summary>
        /// Get the list of included values
        ///</summary>
        public List<string> Filters
        {
            get { return _filters; }
        }
        private readonly List<DateGroupItem> _dateGroupItems = new List<DateGroupItem>();

        public List<DateGroupItem> DateGroupItems
        {
            get { return _dateGroupItems; }
        }

        public bool Blank { get; set; }

        public CalendarType CalendarType { get; set; }


        internal override bool GetValue(Cell cell, RangeAddress rangeAddress)
        {
            object val = cell.Value;
            if (val == null)
                return true;
            if (val is string)
            {
                return Filters.Contains(val.ToString());
            }
            if (val is double)
            {
                return Filters.Contains(val.ToString());
            }
            if (val is DateTime)
            {
                double dbl = cell.Worksheet.Workbook.DateTimeToDouble((DateTime) val);
                return Filters.Contains(dbl.ToString());
            }
            throw new NotImplementedException();
        }

        internal override Func<Cell, bool> GetCellEvaluator(Range range)
        {
            return cell =>
                       {
                           object val = cell.Value;
                           if (val == null)
                               return true;
                           if (val is string)
                           {
                               return Filters.Contains(val.ToString());
                           }
                           if (val is double)
                           {
                               return Filters.Contains(val.ToString());
                           }
                           if (val is DateTime)
                           {
                               double dbl = cell.Worksheet.Workbook.DateTimeToDouble((DateTime) val);
                               return Filters.Contains(dbl.ToString());
                           }
                           throw new NotImplementedException();
                       };
        }
    }
}
